From 6d879f9308d728da29f33a6d61d8293c16458297 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 3 Mar 2006 15:56:03 +0100 Subject: [PATCH] Wait for the devices configured at start-up, before allowing the boot to proceed. This avoids the race (bug #549) that would result in the infamous VFS: Cannot open root device "sda1" or unknown-block(0,0) message even when the hotplug layer had succeeded to configure the device. Note that The Infamous Message has many possible root causes -- this change only fixes one of them. This particular root cause is characterised by successful boots interleaved with unsuccessful ones, and diagnose.py showing both front and backend drivers in the Connected state. Closes bug #549. Signed-off-by: Ewan Mellor --- .../drivers/xen/xenbus/xenbus_probe.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index ca97e341a8..cab6d5bec8 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -884,9 +884,36 @@ void unregister_xenstore_notifier(struct notifier_block *nb) EXPORT_SYMBOL(unregister_xenstore_notifier); +static int all_devices_ready_(struct device *dev, void *data) +{ + struct xenbus_device *xendev = to_xenbus_device(dev); + int *result = data; + int state; + + int err = xenbus_scanf(XBT_NULL, xendev->nodename, "state", "%d", + &state); + if (err != 1 || state != XenbusStateConnected) { + result = 0; + return 1; + } + + return 1; +} + + +static int all_devices_ready(void) +{ + int ready = 1; + bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready, + all_devices_ready_); + return ready; +} + void xenbus_probe(void *unused) { + int i; + BUG_ON((xenstored_ready <= 0)); /* Enumerate devices in xenstore. */ @@ -899,6 +926,28 @@ void xenbus_probe(void *unused) /* Notify others that xenstore is up */ notifier_call_chain(&xenstore_chain, 0, NULL); + + /* On a 10 second timeout, waiting for all devices currently + configured. We need to do this to guarantee that the filesystems + and / or network devices needed for boot are available, before we + can allow the boot to proceed. + + A possible improvement here would be to have the tools add a + per-device flag to the store entry, indicating whether it is needed + at boot time. This would allow people who knew what they were + doing to accelerate their boot slightly, but of course needs tools + or manual intervention to set up those flags correctly. + */ + for (i = 0; i < 10 * HZ; i++) { + if (all_devices_ready()) + return; + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + + printk(KERN_WARNING + "XENBUS: Timeout connecting to devices!\n"); } -- 2.30.2